#include <Python.h>
#include <stdio.h>
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>

typedef struct frame {
	int width;
	int height;
	int fps;
} frame_t;

/* The function to calculate fibonacci sequence */
static int fib(int num)
{
	return num;
}

static frame_t fib2()
{
	frame_t frm;

	frm.width = 1280;
	frm.height = 720;
	frm.fps = 25;

	return frm;
}

/* Wrap the original function to python object */
static PyObject* py_fib(PyObject* self, PyObject* args)
{
	int num;
	int result;

	// transform python object to c int
	if (!PyArg_ParseTuple(args, "i", &num))
		return NULL;

	result = fib(num);

	// transform c int to python object
	return Py_BuildValue("i", result);
}

static PyObject* py_fib2(PyObject* self, PyObject* args)
{
	frame_t frm;
	PyObject* tuple = PyTuple_New(3); // 创建一个包含结果的元组

	frm = fib2();

	PyTuple_SetItem(tuple, 0, PyLong_FromLong(frm.width));
	PyTuple_SetItem(tuple, 1, PyLong_FromLong(frm.height));
	PyTuple_SetItem(tuple, 2, PyLong_FromLong(frm.fps));

	return tuple;
}

static PyObject* py_fib3(PyObject* self, PyObject* args)
{
	int x = 0;
	int y = 0;
	int w = 1280;
	int h = 720;
	int idx = 0;
	int bpp = 3;                       /* RGB888 Byte pre pixel */
	int ndim = 3;                      /* 维度 */
	int size = w * h * 3;              /* 大小，这里最后的 x3 是指 RGB888, 和 ndim 没有关系，如果是 ARGB 格式，则这里就是 x4 */
	npy_intp shape[3] = { h, w, bpp }; /* 形状, 数组的大小需要和 ndim 一致 */
	// npy_intp strides[3] = { w * bpp, bpp, sizeof(uint8_t) };
	static uint8_t* buffer = NULL;

	buffer = (uint8_t*)malloc(size);
	if (!buffer) {
		printf("err: malloc\n");
		return NULL;
	}

	/* 生成渐变色 */
	for (y = 0; y < h; y++) {
		for (x = 0; x < w; x++) {
			idx = (y * w + x) * 3;
			buffer[idx] = 255 - (x * 255) / w; // 从左到右红色逐渐减少
			buffer[idx + 1] = 0;               // 绿色保持不变
			buffer[idx + 2] = (y * 255) / h;   // 从上到下蓝色逐渐增加
		}
	}

	/* 创建一个 NumPy 数组对象 */
	PyObject* pyArray = PyArray_SimpleNewFromData(ndim, shape, NPY_UINT8, buffer);
	if (pyArray == NULL) {
		printf("err: PyArray_SimpleNew\n");
		free(buffer);
		return NULL;
	}

	return Py_BuildValue("N", pyArray);
}

/* Define the methods in module */
static PyMethodDef fibmethods[] = {
	{ "fib", py_fib, METH_VARARGS },
	{ "fib2", py_fib2, METH_VARARGS },
	{ "fib3", py_fib3, METH_VARARGS },
	{ "fib3", py_fib3, METH_VARARGS },
	{ NULL, NULL, 0, NULL }
};

/* Define the module */
static struct PyModuleDef fibmodule = {
	PyModuleDef_HEAD_INIT,
	"Fib", /* name of module */
	NULL,  /* module documentation, may be NULL */
	-1,    /* size of per-interpreter state of the module,
	          or -1 if the module keeps state in global variables. */
	fibmethods
};

/* initialization function */
PyMODINIT_FUNC PyInit_Fib(void)
{
	// 初始化 NumPy C API
	import_array();

	return PyModule_Create(&fibmodule);
}
